using System;
using System.Collections.Generic;
using BSDS.Commands;
using BSDS.Commands.Commands;
using BSDS.Core.Infrastructure.Logging;

namespace BSDS.Service.Logic
{
    /// <summary>
    /// Class prepares the command for dispatching. It substitutes any variables in 
    /// template e.g. @variable with actual value specifed by the class user.
    /// </summary>
    public class CommandExecutor
    {
        private readonly CommandDispatcher commandDispatcher;
        private readonly Logger logger;
        private readonly string commandTemplate;

        public CommandExecutor(CommandDispatcher commandDispatcher, Logger logger, string commandTemplate)
        {
            this.commandDispatcher = commandDispatcher;
            this.logger = logger;
            this.commandTemplate = commandTemplate;
        }

        public ProcessingResult Process(Dictionary<string, string> parameters)
        {
            var commandParts = FillVariableValues(parameters);

            try
            {
                var commandInfo = CommandInfo.Parse(commandParts);

                commandDispatcher.Dispatch(commandInfo);
            }
            catch (Exception e)
            {
                var message = string.Format("Error: \n{0}.", e);

                logger.Log(message);

                return ProcessingResult.Failure;
            }

            return ProcessingResult.Success;
        }

        private string[] FillVariableValues(Dictionary<string, string> parameters)
        {
            var command = commandTemplate;

            foreach (var variableName in parameters.Keys)
            {
                command = command.Replace(variableName, parameters[variableName]);
            }

            var commandParts = command.Split(' ');

            return commandParts;
        }
    }
}